﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using RSEngine.Core;
using RSEngine.Math;

namespace RSEngine.Helper
{
    sealed public class SceneOptimizer
    {

        #region Optimize

        public void Optimize(Scene scene)
        {
            foreach (Layer layer in scene.Layers)
                Optimize_Layer(layer);
        }

        #endregion

        #region Optimize_Layer

        private void Optimize_Layer(Layer layer)
        {
            foreach (RSBase element in layer.Elements)
            {
                if (element.Type == RSType.Node)
                    Optimize_Group((Node)element);
                else if (element.Type == RSType.Mesh)
                    Optimize_Mesh((Mesh)element);
            }
        }

        #endregion

        #region Optimize_Group

        private void Optimize_Group(Node group)
        {
            foreach (Node subGroup in group.Children)
                Optimize_Group(subGroup);

            foreach (Mesh subMesh in group.Meshes)
                Optimize_Mesh(subMesh);
        }

        #endregion

        #region Optimize_Mesh

        private void Optimize_Mesh(Mesh mesh)
        {
            //---- Sub meshes
            foreach (Mesh subMesh in mesh.Children)
                Optimize_Mesh(subMesh);

            foreach (TriangleGeometry geometry in mesh.Geometry)
                Optimize_Geometry(geometry);
        }

        #endregion

        #region Optimize_Geometry

        private void Optimize_Geometry(TriangleGeometry geometry)
        {
            //List<Vector3> Vertexes = new List<Vector3>(3);
            //List<int> TrianglesIndices = new List<int>(3);

            //---- Optimize
            int vertexesCount = geometry.Vertices.Count;
            for (int index1 = 0; index1 < vertexesCount; index1++)
                if (geometry.Vertices[index1] != Vector3.Invalid)
                for (int index2 = index1 + 1; index2 < vertexesCount; index2++)
                    if (geometry.Vertices[index2] != Vector3.Invalid &&
                        geometry.Vertices[index1] == geometry.Vertices[index2])
                    {
                        // Remove the Vertex at "index2"
                        geometry.Vertices[index2] = Vector3.Invalid;

                        // Update the indices
                        for (int ti = 0; ti < geometry.Indices.Count; ti++)
                            if (geometry.Indices[ti] == index2)
                                geometry.Indices[ti] = index1;
                    }

            geometry.Normals.Clear();
            geometry.CalculateNormals();

            //---- Reconstruct
            //for (int index1 = 0; index1 < vertexesCount; index1++)
        }

        #endregion

    }
}
